package com.szp.drug.component.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.szp.drug.component.mapper.DrugAdminMapper;
import com.szp.drug.component.service.api.DrugAdminService;
import com.szp.drug.entity.DrugAdmin;
import com.szp.drug.entity.DrugRole;
import com.szp.drug.exception.AccountAddDuplicateKeyException;
import com.szp.drug.exception.AccountEditDuplicateKeyException;
import com.szp.drug.util.DrugConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 管理员实现类
 * @author SuZePing
 * @create 2021-01-09 21:08
 * @E-mail suzeping10@126.com
 */
@Slf4j
@Service
public class DrugAdminServiceImpl extends ServiceImpl<DrugAdminMapper, DrugAdmin> implements DrugAdminService {

	@Autowired
	private DrugAdminMapper adminMapper;

	@Autowired
	private BCryptPasswordEncoder passwordEncoder;

	/**
	 * 分页获取管理员列表(含关键词搜索)
	 * @param keyword
	 * @param pageNum
	 * @param pageSize
	 * @return
	 */
	@Override
	public PageInfo<DrugAdmin> getPageInfo(String keyword, Integer pageNum, Integer pageSize) {
		// 开启分页
		PageHelper.startPage(pageNum,pageSize);
		QueryWrapper<DrugAdmin> wrapper = new QueryWrapper<>();
		wrapper.eq("deleted","0");
		wrapper.and(w -> w.like("account",keyword)
				.or().like("email",keyword)
				.or().like("name",keyword))
				.orderByAsc("create_time");
		List<DrugAdmin> admins = adminMapper.selectList(wrapper);
		return new PageInfo<>(admins);
	}

	/**
	 * 删除admin
	 * @param userId
	 */
	@Override
	public void removeAdmin(String userId) {
		int update = adminMapper.updateById(new DrugAdmin().setUserId(userId).setDeleted("1"));
		if (update == 0){
			throw new RuntimeException(DrugConstant.MESSAGE_SYSTEM_ERROR_DATAERROR);
		}
	}

	/**
	 * 新增admin
	 * @param admin
	 */
	@Override
	public void saveAdmin(DrugAdmin admin) {
		String password = admin.getPassword();
		admin.setPassword(passwordEncoder.encode(password))// SpringSecurity密码加盐
				.setUserId(IdUtil.fastSimpleUUID().substring(0, 10))
				.setCreateTime(DateUtil.now());
		log.debug("admin:{}",admin);
		try {
			adminMapper.insert(admin);
		} catch (DuplicateKeyException exception) {
			// 用户名重复 抛出异常
			throw new AccountAddDuplicateKeyException(DrugConstant.MESSAGE_ACCOUNT_DUPLICATE);
		}
	}

	/**
	 * 修改admin时回显数据
	 * @param adminId
	 * @return
	 */
	@Override
	public DrugAdmin getAdminById(String adminId) {
		DrugAdmin selAdmin = adminMapper.selectById(adminId);
		log.debug("selAdmin:{}",selAdmin);
		return selAdmin;
	}

	/**
	 * 修改admin
	 * @param admin
	 */
	@Override
	public void editAdmin(DrugAdmin admin) {
		log.debug("admin:{}",admin);
		try {
			adminMapper.updateById(admin);
		} catch (DuplicateKeyException exception) {
			// 用户名重复 抛出异常
			throw new AccountEditDuplicateKeyException(DrugConstant.MESSAGE_ACCOUNT_DUPLICATE);
		}
	}

	/**
	 * 查询该管理员已拥有的角色
	 * @param adminId
	 * @return
	 */
	@Override
	public List<DrugRole> getAssignedRole(String adminId) {
		return adminMapper.selectAssignedRole(adminId);
	}

	/**
	 * 查询该管理员未拥有的角色
	 * @param adminId
	 * @return
	 */
	@Override
	public List<DrugRole> getUnassignedRole(String adminId) {
		return adminMapper.selectUnassignedRole(adminId);
	}

	/**
	 * 为管理员分配角色
	 * @param adminId
	 * @param roleIdList
	 */
	@Override
	public void saveAssignAdminRole(String adminId, List<String> roleIdList) {
		// 先进行删除原本的数据
		adminMapper.deleteAssignAdminRole(adminId);
		// 添加新增的数据
		if (!CollUtil.isEmpty(roleIdList)){
			adminMapper.insertAssignAdminRole(adminId,roleIdList);
		}
	}

	/**
	 * 根据account获取DrugAdmin对象
	 * @param account
	 * @return
	 */
	@Override
	public DrugAdmin getAdminByAccount(String account) {
		QueryWrapper<DrugAdmin> wrapper = new QueryWrapper<>();
		wrapper.eq("account",account);
		return adminMapper.selectOne(wrapper);
	}

}
